package at.markusreich.racecalendar.client.presenter;

import java.util.List;

import at.markusreich.racecalendar.client.model.CalendarEntry;
import at.markusreich.racecalendar.client.service.CalendarServiceAsync;
import at.markusreich.racecalendar.client.view.CalendarWidget;

import com.google.gwt.event.dom.client.HasClickHandlers;
import com.google.gwt.event.shared.HandlerManager;
import com.google.gwt.user.cellview.client.CellTable;
import com.google.gwt.user.client.Window;
import com.google.gwt.user.client.rpc.AsyncCallback;
import com.google.gwt.user.client.ui.HasWidgets;
import com.google.gwt.user.client.ui.Widget;
import com.google.gwt.view.client.AsyncDataProvider;
import com.google.gwt.view.client.HasData;
import com.google.gwt.view.client.Range;

public class CalendarPresenter implements Presenter {

	private List<CalendarEntry> calendarEntries;

	public interface Display {
	    HasClickHandlers getList();
	    Widget asWidget();
	    CellTable<CalendarEntry> getCellTable();
	  }

	private final CalendarServiceAsync rpcService;
	private final HandlerManager eventBus;
	private final Display display;

	public CalendarPresenter(CalendarServiceAsync rpcService, HandlerManager eventBus, Display view) {
	    this.rpcService = rpcService;
	    this.eventBus = eventBus;
	    this.display = view;
	  }

	@Override
	public void go(HasWidgets container) {
		rpcService.getCalendarEntriesList(new AsyncCallback<List<CalendarEntry>>() {
			public void onSuccess(List<CalendarEntry> result) {
		        buildTable(result);
		      }

		      public void onFailure(Throwable caught) {
		        Window.alert("Error selecting calendar entries!");
		      }
		});
		container.add(display.asWidget());
	}

	private void buildTable(final List<CalendarEntry> calendarEntries) {
		final CellTable cellTable = display.getCellTable();
		// Set the total row count. You might send an RPC request to determine
		// the
		// total row count.
		cellTable.setRowCount(calendarEntries.size(), true);

		// Set the range to display. In this case, our visible range is smaller
		// than
		// the data set.
		// cellTable.setVisibleRange(0, 3);

		// Create a data provider.
		AsyncDataProvider<CalendarEntry> dataProvider = new AsyncDataProvider<CalendarEntry>() {
			@Override
			protected void onRangeChanged(HasData<CalendarEntry> display) {
				final Range range = display.getVisibleRange();

				int start = range.getStart();
				int end = start + range.getLength();
				end = end >= calendarEntries.size() ? calendarEntries.size() : end;
				List<CalendarEntry> dataInRange = calendarEntries.subList(start, end);

				// Push the data back into the list.
				cellTable.setRowData(start, dataInRange);
			}
		};

		// Connect the list to the data provider.
		dataProvider.addDataDisplay(display.getCellTable());


	}

}
